#include <string>

#include "ClaveDatoCuba.h"
#include "DatoCuba.h"
#include "EstrategiaHashSHA1.h"
#include "funciones.h"

namespace Toolkit
{

ClaveDatoCuba::ClaveDatoCuba(const DatoCuba &datoCuba,
        const TipoSerializacion &tSerializacion) :
    Clave()
{
    this->claveHasheada = datoCuba.getClaveHasheada();
    this->tSerializacion = tSerializacion;
}

ClaveDatoCuba::ClaveDatoCuba(string claveHasheada,
        const TipoSerializacion &tSerializacion) :
    Clave()
{
    this->claveHasheada = claveHasheada;
    this->tSerializacion = tSerializacion;
}

ClaveDatoCuba::~ClaveDatoCuba()
{
}

void ClaveDatoCuba::serializar(stringstream& stream) const
{
    stream.write(claveHasheada.c_str(), claveHasheada.size());
    agregarTamanoASerializacionComp(stream, tSerializacion);
}

void ClaveDatoCuba::hidratar(stringstream & stream)
{
    int longitudString = 0;

    hidratacionDigito(stream, tSerializacion, longitudString);

    char *bufferDatos = new char[longitudString];
    stream.read(bufferDatos, longitudString);

    this->claveHasheada = "";
    this->claveHasheada.append(bufferDatos, longitudString);

    delete[] bufferDatos;
}

bool ClaveDatoCuba::operator ==(const Clave& clave) const
{
    stringstream claveSerializada;
    clave.serializar(claveSerializada);
    string claveAHashear = claveSerializada.str();

    EstrategiaHashSHA1 estrategiaHashMod;
    string claveHasheadaAux = estrategiaHashMod.hash(claveAHashear);

    return this->claveHasheada == claveHasheadaAux;
}

bool ClaveDatoCuba::operator ==(const Dato& dato) const
{
    return (this->claveHasheada == ((DatoCuba &) dato).getClaveHasheada());
}

bool ClaveDatoCuba::operator <(const Clave &clave) const
{
    stringstream claveSerializada;
    clave.serializar(claveSerializada);
    string claveAHashear = claveSerializada.str();

    EstrategiaHashSHA1 estrategiaHashMod;
    string claveHasheadaAux = estrategiaHashMod.hash(claveAHashear);

    return this->claveHasheada < claveHasheadaAux;
}

bool ClaveDatoCuba::operator <(const Dato &dato) const
{
    return (claveHasheada < ((DatoCuba &) dato).getClaveHasheada());
}

Clave* ClaveDatoCuba::clonar() const
{
    return new ClaveDatoCuba(this->claveHasheada, this->tSerializacion);
}

Clave* ClaveDatoCuba::crearDesdeDato(const Dato& dato) const
{
    return new ClaveDatoCuba((DatoCuba&)dato, this->tSerializacion);
}

}
